package com.testflow.hyh.listener;

import com.alibaba.fastjson.JSON;
import com.testflow.hyh.annotation.PackApiDesc;
import com.testflow.hyh.annotation.TestApiDesc;
import com.testflow.hyh.config.TestManager;
import com.testflow.hyh.testReport.V1.ReportApiRequest;
import com.testflow.hyh.testReport.V1.ReportApiResponse;
import com.testflow.hyh.testReport.V1.ReportInfo;
import com.testflow.hyh.testReport.V2.ApiInfo;
import com.testflow.hyh.testReport.V2.ApiPack;
import com.testflow.hyh.testReport.V2.ApiRequest;
import com.testflow.hyh.testReport.V2.ApiResult;
import com.testflow.hyh.util.MailUtils;
import lombok.extern.slf4j.Slf4j;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.TestListenerAdapter;
import org.testng.internal.ConstructorOrMethod;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * @Author: 何宇航
 * @Description：
 * @DateTime：2022/6/9 0009 17:28
 */
@Slf4j
public class TestngListener extends TestListenerAdapter {

    public static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void onTestSuccess(ITestResult result){
        方法切入V1(result);
    }

    @Override
    public void onTestFailure(ITestResult result) {
        方法切入V1(result);
    }

    @Override
    public void onTestSkipped(ITestResult result) {
        方法切入V1(result);
    }

    public void 方法切入V1(ITestResult result) {
        //获取上一个方法执行的log日志
        List<String> output = Reporter.getOutput(result);
        //获取方法载体
        ConstructorOrMethod constructorOrMethod = result.getMethod().getConstructorOrMethod();
        //判断当前方法上是否包含@TestApiDesc注解，如果包含此注解，那么解析注解所有参数的值
        if (constructorOrMethod.getMethod().isAnnotationPresent(TestApiDesc.class)) {
            List<ReportApiResponse> apiResponses = new ArrayList<>();
            for (String response : output) {
                ReportApiResponse reportApiResponse = new ReportApiResponse();
                reportApiResponse.setState(result.getStatus());
                reportApiResponse.setElapseTime(result.getEndMillis() - result.getStartMillis());
                reportApiResponse.setResponse(response);
                apiResponses.add(reportApiResponse);
            }
            //解析TestApiDesc注解中的值
            TestApiDesc testApiDesc = constructorOrMethod.getMethod().getAnnotation(TestApiDesc.class);
            ReportApiRequest request = new ReportApiRequest();
            request.setApiName(testApiDesc.apiName())
                    .setApiUrl(testApiDesc.apiUrl())
                    .setApiTestState(result.getStatus())
                    .setApiMethod(testApiDesc.apiMethod().toString())
                    .setTestInterfaceStartTime(sdf.format(new Date(result.getStartMillis())))
                    .setTestInterfaceEndTime(sdf.format(new Date(result.getEndMillis())))
                    .setTestInterfaceTotalTime(result.getEndMillis() - result.getStartMillis())
                    .setTestCustomRemark(testApiDesc.apiRemark())
                    .setApiResponse(apiResponses);
            TestManager.requestList.add(request);
        }
    }

    public void 方法切入V2(ITestResult result){
        //获取上一个方法执行的log日志
        List<String> output = Reporter.getOutput(result);
        //获取方法载体
        ConstructorOrMethod constructorOrMethod = result.getMethod().getConstructorOrMethod();
        if(result.getTestClass().getRealClass().isAnnotationPresent(PackApiDesc.class)){
            PackApiDesc packApiDesc = result.getTestClass().getRealClass().getAnnotation(PackApiDesc.class);
            if(constructorOrMethod.getMethod().isAnnotationPresent(TestApiDesc.class)){
                List<ApiResult> apiResultList = new ArrayList<>();
                for (String log : output) {
                    ApiResult apiResult = new ApiResult();
                    apiResult.setState(result.getStatus());
                    apiResult.setElapseTime(result.getEndMillis()-result.getStartMillis());
                    apiResult.setResponse(log);
                    apiResultList.add(apiResult);
                }
                List<ApiRequest> apiRequestList = new ArrayList<>();
                //解析TestApiDesc注解中的值
                TestApiDesc testApiDesc = constructorOrMethod.getMethod().getAnnotation(TestApiDesc.class);
                ApiRequest request = new ApiRequest();
                request.setApiName(testApiDesc.apiName())
                        .setApiUrl(testApiDesc.apiUrl())
                        .setApiTestState(result.getStatus())
                        .setApiMethod(testApiDesc.apiMethod().toString())
                        .setTestInterfaceStartTime(sdf.format(new Date(result.getStartMillis())))
                        .setTestInterfaceEndTime(sdf.format(new Date(result.getEndMillis())))
                        .setTestInterfaceTotalTime(result.getEndMillis()-result.getStartMillis())
                        .setTestCustomRemark(testApiDesc.apiRemark())
                        .setApiResultList(apiResultList);
                apiRequestList.add(request);
                //组合参数
                ApiPack pack = new ApiPack();
                pack.setPackName(packApiDesc.packName());
                pack.setPackAuthor(packApiDesc.packAuthor());
                pack.setPackCreateTime(packApiDesc.packCreateTime());
                pack.setApiRequestList(apiRequestList);
                TestManager.apiPackList.add(pack);
            }
        }
    }

    @Override
    public void onFinish(ITestContext context) {
        mergeResultV1(context);
    }

    /**
     * 版本1
     * @param context
     */
    public void mergeResultV1(ITestContext context){
        ReportInfo reportInfo = new ReportInfo();
        reportInfo.setTestSuccess(context.getPassedTests().size());
        reportInfo.setTestFail(context.getFailedTests().size());
        reportInfo.setRequestList(TestManager.requestList);
        log.info("【成功的用例：{} 个】", context.getPassedTests().size());
        log.info("【失败的用例：{} 个】", context.getFailedTests().size());
        //发送邮件
        MailUtils.send163Mail("duanwei0412@163.com","测试结果集",reportInfo);
    }

    /**
     * 版本2
     * @param context
     */
//    public void mergeResultV2(ITestContext context){
//        ApiInfo apiInfo = new ApiInfo();
//        apiInfo.setTestSuccess(context.getPassedTests().size());
//        apiInfo.setTestFail(context.getFailedTests().size());
//        apiInfo.setApiPacks(TestManager.apiPackList);
//        System.out.println(JSON.toJSONString(apiInfo));
//        log.info("【成功的用例：{} 个】", context.getPassedTests().size());
//        log.info("【失败的用例：{} 个】", context.getFailedTests().size());
//        //发送邮件
//        MailUtils.send163Mail("duanwei0412@163.com","测试结果集",apiInfo);
//    }
}
